package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tbit.common.entity.MachineOpLog;
import com.tbit.common.utils.MACUtils;
import com.tbit.uqbike.constant.*;
import com.tbit.uqbike.constant.enums.OrderStatusEnum;
import com.tbit.uqbike.enums.OrderAnalyze;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.OrderHelper;
import com.tbit.uqbike.object.business.OrderInfo;
import com.tbit.uqbike.object.business.PageData;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.pojo.bo.MannedBatchBindBO;
import com.tbit.uqbike.object.pojo.bo.MannedBindingBO;
import com.tbit.uqbike.object.pojo.dto.CommonDTO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.service.base.MQProducer;
import com.tbit.uqbike.service.base.RedisService;
import com.tbit.uqbike.service.base.RedisService1;
import com.tbit.uqbike.service.business.*;
import com.tbit.uqbike.service.rpcservice.PurviewService;
import com.tbit.uqbike.webmanager.business.machine_op_log.service.MachineOpLogService;
import com.tbit.uqbike.webmanager.dao.core.*;
import com.tbit.uqbike.webmanager.dao.log.OrderLogDao;
import com.tbit.uqbike.webmanager.dao.log.ReturnBikeLogDao;
import com.tbit.uqbike.webmanager.dao.log.RuleRideLogDao;
import com.tbit.uqbike.webmanager.dao.ter.TerAttrExDao;
import com.tbit.uqbike.webmanager.util.RedisUtil;
import com.tbit.uqbike.webmanager.util.StringUtils;
import com.tbit.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service("terControlService")
@Slf4j
public class TerControlServiceImpl implements TerControlService {
    @Autowired
    private MQProducer mqProducer;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RedisService1 redisService1;
    @Autowired
    private MachineDao machineMapper;
    @Autowired
    private PurviewService purviewService;
    @Autowired
    private OrderLogDao orderLogDao;
    @Autowired
    private AccountUserDao accountUserDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private RuleRideLogDao ruleRideLogDao;
    @Autowired
    private MachineBorrowDao machineBorrowDao;
    @Autowired
    private ParkDao parkDao;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private TerAttrExDao terAttrExDao;
    @Autowired
    private AccountService accountService;
    @Autowired
    private ReturnBikeLogDao returnBikeLogDao;
    @Autowired
    private TerOfflineOrderService terOfflineOrderService;
    @Autowired
    private MannedService mannedService;
    @Autowired
    private MachineOpLogService machineOpLogService;
    @Resource
    private HolderAccountBoundService holderAccountBoundService;
    @Autowired
    private AccountDao accountDao;

    private static void intStrCheck(String str) {
        try {
            Integer i = Integer.parseInt(str);
            if (i < 0) {
                throw new BaseException(SystemCodeEnum.CONTROL_PARAM_ERROR);
            }
        } catch (Exception e) {
            throw new BaseException(SystemCodeEnum.CONTROL_PARAM_ERROR);
        }
    }

    private static String paramNameCheck(String str) {
        if (null == str || str.trim().isEmpty()) {
            throw new BaseException(SystemCodeEnum.CONTROL_PARAM_ERROR);
        }
        String nStr = str.trim();
        if (!nStr.endsWith(";")) {
            nStr = String.format("%s;", nStr);
        }
        return nStr;
    }

    @Override
    public OrderInfo getOrderInfo(String userCode, String controlType, String paramName, String desc, Integer businessCode) {
        OrderInfo oi = new OrderInfo();
        if (null == desc && businessCode == null) {
            throw new BaseException(SystemCodeEnum.MISS_BUSINESSCODE_OR_DESC);
        }
        oi.setUserCode(userCode);
        if (Objects.equals(ControlTypeConstant.CONTROL_TYPE_GET, controlType)) {
            paramName = paramNameCheck(paramName);
        } else if (Objects.equals(ControlTypeConstant.CONTROL_TYPE_SET, controlType)) {
            paramName = paramNameCheck(paramName);
        } else if (Objects.equals(ControlTypeConstant.CONTROL_TYPE_VOICE, controlType)) {
            intStrCheck(paramName);
        } else if (Objects.equals(ControlTypeConstant.CONTROL_TYPE_CONTROL, controlType)) {
            intStrCheck(paramName);
        } else if (Objects.equals(ControlTypeConstant.CONTROL_TYPE_TAKEPIC, controlType)) {
            intStrCheck(paramName);
        } else if (Objects.equals(ControlTypeConstant.CONTROL_TYPE_UPLOADPIC, controlType)) {
            intStrCheck(paramName);
        } else {
            throw new BaseException(SystemCodeEnum.CONTROL_TYPE_ERROR);
        }
        oi.setParamName(paramName);
        oi.setControlType(controlType);
        oi.setDesc(desc);
        oi.setBusinessCode(businessCode);
        return oi;
    }

    @Override
    public String sendControl(LoginInfo loginInfo, OrderInfo orderInfo) {
        Machine machine = machineMapper.selectByKey(orderInfo.getUserCode());
        if (null == machine) {
            throw new BaseException(SystemCodeEnum.MACHINE_NOT_EXIST);
        }
        if (!purviewService.purviewCheck(loginInfo.id, machine)) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        // 初始化指令信息
        orderInfo.initOrderInfo(machine);
        /**查询消息所在的队列名称*/
        String route_key = redisService1.get(RedisUtil.getTerHashId(machine.getMachineNO()), RedisConstant.REDIS_TER_ROUTE_KEY);
        /**封装消息*/
        TerMsg termsg = OrderInfo.parseTerMsg(orderInfo);
        /**发送到MQ*/
        log.info(String.format("发送指令，route_key=%s,routeKey=%s,MQ_MSG_ID_CONTROL_TER=%s,termsg=%s", route_key, RabbitMQData.routeKey, GatewayProtocol.MQ_MSG_ID_CONTROL_TER, JSON.toJSONString(termsg)));
        mqProducer.sendDataToQueue(route_key, RabbitMQData.routeKey, GatewayProtocol.MQ_MSG_ID_CONTROL_TER, termsg);
        OrderLog orderLog = saveOrderLog(loginInfo, orderInfo);

        // 插入车辆操作日志
        if (ControlTypeConstant.CONTROL_TYPE_CONTROL.equals(orderInfo.getControlType())) {
            String detail = "指令流水号：" + orderInfo.getSerNo() + "\n指令备注：" + orderInfo.getDesc();
            MachineOpLog opLog = getOpLogByType(orderInfo.getParamName());
            if (opLog != null) {
                machineOpLogService.batchAddRecord(opLog.getOperation(), opLog.getOpType(), true, detail, Collections.singletonList(machine));
            }
        }

        //低电换电提醒和删除临停记录操作
        threadPoolTaskExecutor.execute(() -> {
            try {
                if (ControlTypeConstant.CONTROL_TYPE_UNLOCK.equals(orderInfo.getParamName())) {
                    //开锁
                    MachineBorrow machineBorrowInDb = machineBorrowDao.getByMachineId(machine.getMachineId());
                    if (machineBorrowInDb != null) {
                        //轮询结果
                        String serNo = orderInfo.getSerNo();
                        for (int i = 0; i < 30; i++) {
                            //一秒钟轮旋一次，轮询30次
                            Thread.sleep(1000);
                            OrderInfo reply = OrderHelper.getOrderInfo(serNo, redisService1);
                            log.info(String.format("轮询结果%s", reply == null ? "null" : JSON.toJSON(reply)));
                            if (reply != null && ControlTypeConstant.CONTROL_TYPE_SUCC.equals(reply.getRsp())) {
                                //有订单的，需要删除临停记录,并且告诉运维端判断低电换电提醒
                                parkDao.delByUserId(machineBorrowInDb.getUserId());
                                log.info(String.format("有订单开锁删除临停记录,userId=%s", machineBorrowInDb.getUserId()));
                                //删除临停记录后，修改终端静止起止时间
                                TerAttrEx terAttrEx = new TerAttrEx(machine.getMachineNO(), "tLST", "0", new Date());
                                log.info(String.format("有订单开锁修改终端静止起止时间,machineNO=%s", machine.getMachineNO()));
                                terAttrExDao.updateAttrDt(terAttrEx);
                                String machineBorrowKey = RedisKeyConstant.getMachineBorrowKey(orderInfo.getMachineNo());
                                redisService1.add(machineBorrowKey, DateUtil.now());
                                log.info(String.format("开锁发送运维端低电换电提醒成功,key=%s", machineBorrowKey));
                                //断电往回骑记录时间
                                redisService.add(String.format("BackCyclingTimeStart#%s", machine.getMachineNO()), DateTimeUtil.getNowTime(), 600);
                                return;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                log.error("开锁发送运维端低点换电提醒/删除临停记录/修改终端静止起止时间失败");
            }
        });
        // 赋值id
        if (null != orderLog) {
            orderInfo.setLogid(orderLog.getLogId());
        }
        OrderHelper.cacheOrderInfo(orderInfo, redisService1);
        return orderInfo.getSerNo();
    }

    private MachineOpLog getOpLogByType(String type) {
        switch (type) {
            case ControlTypeConstant.CONTROL_TYPE_BIKE_LOCK:
                return MachineOpLog.builder()
                        .operation("车辆锁")
                        .opType("关闭")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_UNSTART:
                return MachineOpLog.builder()
                        .operation("车辆断电")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_UNLOCK:
                return MachineOpLog.builder()
                        .operation("车辆锁")
                        .opType("开启")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_LOCATE:
                return MachineOpLog.builder()
                        .operation("定位")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_FIND:
                return MachineOpLog.builder()
                        .operation("寻车")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_RESTART:
                return MachineOpLog.builder()
                        .operation("重启")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_BATTERYDE:
                return MachineOpLog.builder()
                        .operation("电池锁")
                        .opType("打开")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_BATTERYRIDE:
                return MachineOpLog.builder()
                        .operation("电池锁")
                        .opType("关闭")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_OPEN_HELMET:
                return MachineOpLog.builder()
                        .operation("头盔锁")
                        .opType("打开")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_CLOSE_HELMET:
                return MachineOpLog.builder()
                        .operation("头盔锁")
                        .opType("关闭")
                        .build();
            case ControlTypeConstant.CONTROL_TYPE_FORCE_CLOSE_SMART_HELMET:
                return MachineOpLog.builder()
                        .operation("智能头盔锁")
                        .opType("强制关闭")
                        .build();
            default:
                return null;
        }
    }

    private OrderLog saveOrderLog(LoginInfo loginInfo, OrderInfo orderInfo) {
        OrderLog orderLog = null;
        try {
            // 插入日志
            orderLog = OrderInfo.parseOrderLog(orderInfo);
            orderLog.setOptype(loginInfo.type);
            orderLog.setOpid(loginInfo.id);
            orderLog.setOpPhone(loginInfo.phone);
            orderLog.setAccountUserId(loginInfo.accountUserId);
            orderLogDao.insert(orderLog);
        } catch (Exception e) {
            log.error(String.format("插入指令日志失败:%s", JSONObject.toJSONString(orderLog)));
        }
        return orderLog;
    }

    @Override
    public void sendRspHandle(String serNO, String controlRet) {
        OrderHelper.updateOrderSendRsp(serNO, controlRet, redisService1);
    }

    @Override
    public void respHandle(String serNO, String controlRet, String paramRet, List<String> picList) {
        OrderInfo info = OrderHelper.updateOrderRsp(serNO, controlRet, paramRet, redisService1, picList);
        // 更新载人状态
        mannedService.updateIfPresent(serNO, paramRet);
        // 更新数据库
        Map<String, Object> map = new HashMap<>();
        map.put("serNo", serNO);
        map.put("rspdt", new Date());
        map.put("rspret", OrderHelper.ORDER_RET_SUCC);
        map.put("rspcontent", paramRet);
        orderLogDao.updateOrderRspInfo(map);
        if (null != info && StrUtil.isNotBlank(info.getSerNo())) {
            /**兼容摄像头图片上传*/
            if (picList != null && !picList.isEmpty()) {
                List<RuleRidePhotoLog> logs = new ArrayList<>();
                Date addTime = new Date();
                picList.forEach(s -> {
                    RuleRidePhotoLog ruleRidePhotoLog = new RuleRidePhotoLog();
                    ruleRidePhotoLog.setFtpUrl(s);
                    ruleRidePhotoLog.setMachineNO(info.getMachineNo());
                    ruleRidePhotoLog.setType(2);
                    ruleRidePhotoLog.setAddTime(addTime);
                    ruleRidePhotoLog.setRemark("");
                    logs.add(ruleRidePhotoLog);
                });
                ruleRideLogDao.addBatch(logs);
            }
        }
    }

    @Override
    public OrderInfo getOrderRsp(LoginInfo loginInfo, String serNo) {
        // 获取应答不鉴权
        OrderInfo order = OrderHelper.getOrderInfo(serNo, redisService1);
        return order;
    }

    @Override
    public PageData<List<OrderLog>> queryOrderHis(LoginInfo li, Integer rowCount, Integer pageNO, Long startDt, Long endDt,
                                                  String userCode, String machineNO, String phone,Integer accountUserId,Integer brandId) {
        Map<String, Object> map = new HashMap<>();
        boolean page = null != rowCount && null != pageNO;
        if (page) {
            map.put("start", rowCount * (pageNO - 1));
            map.put("rowCount", rowCount);
        }
        if (null != startDt) {
            map.put("startDt", new Date(startDt));
        }
        if (null != endDt) {
            map.put("endDt", new Date(endDt));
        }
        map.put("userCode", userCode);
        map.put("machineNO", machineNO);
        //获取当前登录账户的所有
        List<Integer> accountIdList;
        //获取当前账号所属品牌的所有品牌+加盟商+区域id,管理员获取所有
        if (li.roleIsAdmin()) {
            accountIdList = accountService.getAllId(brandId);
        } else {
            //获取所有的accountId
            accountIdList = this.getAccountIds(li,brandId);
        }
        if (machineNO != null) {
            Machine machine = machineMapper.selectByKey(machineNO);
            if (machine == null || !accountIdList.contains(machine.getAccountId())) {
                throw new BaseException(SystemCodeEnum.MACHINE_NOT_EXIST);
            }
        }

        if (userCode != null) {
            Machine machine = machineMapper.selectByKey(userCode);
            if (machine == null || !accountIdList.contains(machine.getAccountId())) {
                throw new BaseException(SystemCodeEnum.MACHINE_NOT_EXIST);
            }
        }
        List<Integer> opIdList = new ArrayList<>();
        List<Integer> opTypeList = new ArrayList<>();
        if (StringUtils.isNotEmpty(phone) || Objects.nonNull(accountUserId)) {
            //查平台账号
            List<OpMsg> opMsgList = accountUserDao.getOpMsgByUserIdAndPhone(phone,accountUserId);
            for (OpMsg opMsg : opMsgList) {
                if (Objects.equals(1, opMsg.getAccountId())) {
                    //管理员默认是0，但是以前的管理员有两个绑定
                    opMsg.setOpId(0);
                }
                if (accountIdList.contains(opMsg.getAccountId())) {
                    opIdList.add(opMsg.getOpId());
                    opTypeList.add(opMsg.getOpType());
                }
            }
            if (StringUtils.isNotEmpty(phone) && Objects.isNull(accountUserId)) {
                //查用户
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("phone", phone);
                paramMap.put("accountId", null);
                List<User> userList = userDao.getByAccountIdAndPhone(paramMap);
                if (CollectionUtil.isNotEmpty(userList)) {
                    userList.forEach(a -> opIdList.add(a.getUserId()));
                    opTypeList.add(11);
                }
            }
            if (CollectionUtil.isEmpty(opIdList)) {
                throw new BaseException("运维人员或用户不存在");
            }
        }
        map.put("opIdList", opIdList);
        map.put("opTypeList", opTypeList);
//        log.info("queryOrderHis------>map:{}",JSON.toJSONString(map));
        List<OrderLog> data = orderLogDao.selectOrderLogByParam(map);
        HashMap<String, Object> resMap = new HashMap<>();
        for (OrderLog item : data) {
            String rspContent = item.getRspContent();
            String convertRsp = OrderHisConstant.orderHisMap.get(rspContent);
            if (StrUtil.isNotBlank(convertRsp)) {
                resMap.put("ret", rspContent);
                resMap.put("msg", convertRsp);
                item.setRspcontent(JSONUtil.toJsonStr(resMap));
            } else {
                item.setRspcontent(rspContent);
            }

        }
        int total = orderLogDao.selectOrderLogCntByParam(map);
        // 丰富手机号
        List<Integer> adminIds = new LinkedList<>();
        Map<Integer, String> adminMap = new HashMap<>();
        List<Integer> userIds = new LinkedList<>();
        Map<Integer, String> userMap = new HashMap<>();
        for (OrderLog item : data) {
            //解析指令
            String analyze = OrderAnalyze.analyze(item.getOrderType(), item.getOrderContent());
            if (StringUtils.isNotEmpty(analyze)) {
                item.setOrderContentNew(analyze);
            }
            if (Objects.equals(UserConstant.USER, item.getOpType())) {
                if (!userMap.containsKey(item.getOpId())) {
                    userMap.put(item.getOpId(), "");
                    userIds.add(item.getOpId());
                }
            } else {
                if (!adminMap.containsKey(item.getAccountUserId())) {
                    adminMap.put(item.getAccountUserId(), "");
                    adminIds.add(item.getAccountUserId());
                }
            }
        }
        Map<String, Object> param = new HashMap<>();
        if (!adminIds.isEmpty()) {
            List<AccountUser> accountUserList = accountUserDao.getAccountUserByIds(adminIds);
            for (AccountUser item : accountUserList) {
                adminMap.put(item.getAccountUserId(), item.getPhone());
            }
        }
        if (!userIds.isEmpty()) {
            param.put("userIds", userIds);
            List<User> userList = userDao.getByUserIds(param);
            for (User item : userList) {
                userMap.put(item.getUserId(), item.getPhone());
            }
        }
        for (OrderLog item : data) {
            if (Objects.equals(UserConstant.USER, item.getOpType())) {
                item.setOpPhone(userMap.get(item.getOpId()));
            } else {
                item.setOpPhone(adminMap.get(item.getAccountUserId()));
            }
        }

        if (!data.isEmpty()) {
            if (org.apache.commons.lang3.StringUtils.isAllBlank(userCode, machineNO)) {
                return new PageData<>(data, total);
            }
            long minDt = data.stream().mapToLong(v -> v.getOpTime().getTime()).min().getAsLong();
            long maxDt = data.stream().mapToLong(v -> v.getOpTime().getTime()).max().getAsLong();

            CommonDTO commonDTO = new CommonDTO();
            commonDTO.setUserCode(userCode);
            commonDTO.setMachineNO(machineNO);
            commonDTO.setStartDt(minDt);
            commonDTO.setEndDt(maxDt);
            List<ReturnBikeLog> bikeLogs = returnBikeLogDao.selectInfo(commonDTO);
            for (OrderLog orderLog : data) {
                if ("预还车信息获取".equals(orderLog.getRemark())) {
                    Date opTime = orderLog.getOpTime();
                    DateTime offseTime = DateUtil.offsetMinute(opTime, 1);

                    Optional<ReturnBikeLog> bikeLogOptional = bikeLogs.stream()
                            .filter(v -> {
                                long addTime = DateUtil.parseDateTime(v.getAddTime()).getTime();
                                return addTime > opTime.getTime() && addTime < offseTime.getTime();
                            })
                            .min(Comparator.comparing(v -> DateUtil.parseDateTime(v.getAddTime()).getTime()));
                    if (bikeLogOptional.isPresent()) {
                        ReturnBikeLog bikeLog = bikeLogOptional.get();
                        OrderStatusEnum orderStatusEnum = OrderStatusEnum.of(bikeLog.getReturnCode());
                        if (orderStatusEnum != null) {
                            orderLog.setRemark(orderLog.getRemark() + "【最近还车日志:" + bikeLog.getAddTime() + " " + orderStatusEnum.getDesc() + "】");
                        }
                    }
                }
            }
        }
        return new PageData<>(data, total);
    }

    @Override
    public void mannedBinding(MannedBatchBindBO bo) {

        List<TerOfflineOrder> terOfflineOrders = new ArrayList<>();
        List<OrderLog> orderInfos = new ArrayList<>();

        LoginInfo loginInfo = bo.getLoginInfo();
        for (MannedBindingBO mannedBinding : bo.getMannedBindingList()) {
            Machine machine = mannedBinding.getMachine();
            Manned manned = mannedBinding.getManned();
            if (machine != null && manned != null) {
                boolean bindingStatus = StrUtil.isBlank(mannedBinding.getMannedBinding().getMannedNo());
                String mannedNo = bindingStatus ? "0" : mannedBinding.getMannedBinding().getMannedNo();
                String desc = bindingStatus ? "解绑" : "绑定";
                String mannedMac = MACUtils.getMacFromCode(mannedNo);

                String paramName = ControlTypeConstant.MANNED_BOUND + "=" + mannedMac + ";";

                OrderInfo orderInfo = new OrderInfo();
                orderInfo.initOrderInfo(machine);
                orderInfo.setParamName(paramName);
                orderInfo.setControlType(ControlTypeConstant.CONTROL_TYPE_SET);
                orderInfo.setDesc("载人设备" + desc);
                OrderLog orderLog = OrderInfo.parseOrderLog(orderInfo);
                orderLog.setOptype(loginInfo.type);
                orderLog.setOpid(loginInfo.id);
                orderLog.setOpPhone(loginInfo.phone);
                orderLog.setAccountUserId(loginInfo.accountUserId);
                orderInfos.add(orderLog);
                manned.setSerNo(orderInfo.getSerNo());
                manned.setMannedMac(mannedMac);

                String routeKey = redisService1.get(RedisUtil.getTerHashId(machine.getMachineNO()), RedisConstant.REDIS_TER_ROUTE_KEY);
                // 不在线，发送离线指令
                if (StrUtil.isBlank(routeKey)) {
                    TerOfflineOrder terOfflineOrder = TerOfflineOrder.of(orderInfo.getSerNo(), ControlTypeConstant.CONTROL_TYPE_SET,
                            RabbitMQData.routeKey, machine.getMachineNO(), new Date(), paramName, mannedMac, "载人设备离线指令");
                    redisService1.rPush(RedisUtil.getTerOfflineOrderHashId(terOfflineOrder.getMachineNo()), JSONObject.toJSONString(terOfflineOrder));
                    terOfflineOrders.add(terOfflineOrder);
                }
                // 在线指令
                else {
                    TerMsg termsg = OrderInfo.parseTerMsg(orderInfo);
                    mqProducer.sendDataToQueue(routeKey, RabbitMQData.routeKey, GatewayProtocol.MQ_MSG_ID_CONTROL_TER, termsg);
                }
            }
        }

        if (CollectionUtil.isNotEmpty(orderInfos)) {
            orderLogDao.batchAdd(orderInfos);
        }

        if (CollUtil.isNotEmpty(terOfflineOrders)) {
            terOfflineOrderService.createBatch(terOfflineOrders);
        }
    }

    /**
     * @description: 获取根据不同情况获取所有accountId
     * @author: mo.shanyong
     * @date: 2025/2/27 14:00
     * @param: info 登录用户
     * @param: brandId 品牌id
     * @return: java.util.List<java.lang.Integer>
     */
    private List<Integer> getAccountIds(LoginInfo info,Integer brandId){
        //品牌id为空，说明是订单详情页的指令日志调用（运维端、管理端都有）
        if (Objects.isNull(brandId)){
            brandId = info.getId();
            if (!UserConstant.USER_BRAND.equals(info.getType())) {
                brandId = accountService.getBrandId(info.getId());
            }
           return accountService.getAllId(brandId);
        }
        //品牌id不为空，说明是管理平台车辆操作日志菜单调用接口，这里需要按品牌以及当前登录人的等级返回响应的区域id
        //当前登录账号是否绑定区域
        List<Account> accountList = holderAccountBoundService.getAccountByUserId(info.getAccountUserId());
        if (CollectionUtil.isNotEmpty(accountList)){
            return accountList.stream().map(Account::getAccountId).collect(Collectors.toList());
        }
        //获取能查看的所有的账户id
        return this.getAllAccountId(brandId, info);
    }

    /**
     * @description: 根据品牌id获取所有的区域的、加盟商的id
     * @author: mo.shanyong
     * @date: 2025/2/24 17:25
     * @param: brandId 品牌id
     * @return: java.util.List<java.lang.Integer>
     */
    private List<Integer> getAllAccountId(Integer brandId,LoginInfo info){
        if (UserConstant.USER_ADMIN.equals(info.type) || UserConstant.USER_BRAND.equals(info.type)) {
            //获取全部的id(品牌id、加盟商id、区域id)
            return accountDao.getAllId(brandId);
        } else if (UserConstant.USER_FRANCHISEE.equals(info.type)) {//加盟商账户可以获取所有加盟商和区域的用户
            //加盟商Id
            List<Integer> allIdList = accountDao.getAccountByParentId(brandId);
            if (CollectionUtils.isNotEmpty(allIdList)) {
                //区域id
                List<Integer> accountIdList = accountDao.getAllAccountIdByIds(allIdList);
                allIdList.addAll(accountIdList);
            }
            return allIdList;
        }
        //区域用户只能获取所有的区域用户
        return accountDao.getAllAccountIdByIds(Collections.singletonList(brandId));
    }

}
